package com.corpgovernment.travelstandard.impl;

import com.corpgovernment.api.travelstandard.enums.AreaTypeEnum;
import com.corpgovernment.api.travelstandard.service.ICityConfigService;
import com.corpgovernment.api.travelstandard.utils.MyMap;
import com.corpgovernment.api.travelstandard.vo.*;
import com.corpgovernment.basicdata.bo.HotelCityBo;
import com.corpgovernment.common.base.Page;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.enums.ExceptionCodeEnum;
import com.corpgovernment.common.utils.ListUtils;
import com.corpgovernment.common.utils.ObjectUtils;
import com.corpgovernment.common.utils.PageUtils;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.dataloader.BasicDataClientLoader;
import com.corpgovernment.travelstandard.entity.db.TravelStandardCityConfig;
import com.corpgovernment.travelstandard.mapper.CityConfigMapper;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.shard.context.PageContext;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CityConfigService extends TravelStandardBaseService implements ICityConfigService {

    @Autowired
    private CityConfigMapper cityConfigMapper;

    @Autowired
    private BasicDataClientLoader basicDataClientLoader;

    @Override
    public void insert(CityConfigVo model) {
        TravelStandardCityConfig travelStandardCityConfig = ObjectUtils.copyProperties(model, TravelStandardCityConfig.class);
        cityConfigMapper.insertSelective(travelStandardCityConfig);
//        insertOperateLog(travelStandardCityConfig);
    }

    @Override
    public int delete(Long id) {
//        deleteOperateLog(String.valueOf(id));
        return cityConfigMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int update(CityConfigVo model) {
        TravelStandardCityConfig travelStandardCityConfig =  ObjectUtils.copyProperties(model, TravelStandardCityConfig.class);
        try {
            TravelStandardCityConfig oldValue = findById(model.getId());
//            updateOperateLog(oldValue, travelStandardCityConfig);
        } catch (Exception e) {
            log.error("更新操作获取查询失败,CityConfigService.update");
        }
        return cityConfigMapper.updateByPrimaryKeySelective(travelStandardCityConfig);
    }

    private TravelStandardCityConfig findById(Long id) {
        TravelStandardCityConfig result = cityConfigMapper.selectByPrimaryKey(id);
        if (result == null || result.getStatus() != 0) {
            return null;
        }
        return result;
    }

    @Override
    public CityConfigVo get(Long id) {
        return  ObjectUtils.copyProperties(findById(id), CityConfigVo.class);
    }

    @Override
    public MyMap<String, CityVo> getCityInfoList(AreaConfigVo areaConfigVo) {
        List<TravelStandardCityConfig> cityConfigVoList = cityConfigMapper.listByOrgIdAreaId(areaConfigVo.getId(), areaConfigVo.getOrgId());
        MyMap<String, CityVo> map = null;
        if (!CollectionUtils.isEmpty(cityConfigVoList)) {
            List<HotelCityBo> cityBoList = basicDataClientLoader.searchByCityIds(cityConfigVoList.stream()
                    .map(TravelStandardCityConfig::getCityCode).collect(Collectors.toList()));
            Map<String, HotelCityBo> cityMap = new HashMap<>(cityBoList.size());
            if(CollectionUtils.isNotEmpty(cityBoList)) {
                cityMap = cityBoList.stream().collect(Collectors.toMap(
                        HotelCityBo::getCityId, hotelCityBo -> hotelCityBo));
            }
            map = new MyMap<>();
            for (TravelStandardCityConfig travel : cityConfigVoList) {
                if(CollectionUtils.isNotEmpty(cityMap) && travel.getCityCode() != null && !Objects.isNull(cityMap.get(travel.getCityCode()))) {
                    cityMap.get(travel.getCityCode());
                    travel.setCityName(cityMap.get(travel.getCityCode()).getCityName());
                    // 城市首字母
                    travel.setCityNameEn(cityMap.get(travel.getCityCode()).getFirstChar());
                }
                if (AreaTypeEnum.HOTEL_TYPE_0.getCode().equals(areaConfigVo.getHotelType())){
                    map.add(travel.getCityNameEn(),  ObjectUtils.copyProperties(travel, CityVo.class));
                }else{
                    CityVo cityVo = new CityVo();
                    cityVo.setId(travel.getId());
                    cityVo.setCityCode(travel.getCountryCode());
                    cityVo.setCityName(travel.getCountryName());
                    map.add(travel.getCountryNameEn(), cityVo);
                }
            }
        }
        return map;
    }

    @Override
    public int updateAreaIdByAreaId(Long areaId, Long oriAreaId) {
//        deleteOperateLog(String.valueOf(oriAreaId));
        return cityConfigMapper.updateAreaIdByAreaId(areaId, oriAreaId);
    }

    @Override
    public int updateAreaIdById(Long id, Long areaId) {
//        deleteOperateLog(String.valueOf(id));
        return cityConfigMapper.updateAreaIdById(id, areaId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map addCity(AddCityVo addCityVo) {
        Long areaId = addCityVo.getAreaId();
        String orgid = addCityVo.getOrgid();
        Date date = new Date();
        //需要移动的城市
        List<CityNode> configuredCityList = addCityVo.getConfiguredCity();
        //如果其他区域配置城市列表为空，为第一次调用：新增不在的城市；返回已存在的城市（不含【其它城市】地区）；移动在【其它城市】地区的城市
        if (CollectionUtils.isEmpty(configuredCityList)) {
            //用户新增城市
            List<CityNode> cityNodeList = addCityVo.getCity();
            if (CollectionUtils.isEmpty(cityNodeList)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.CITY_NODE_PARAMS_IS_NULL);
            }
            //当前组织下所有城市
            List<TravelStandardCityConfig> cityInfoList = cityConfigMapper.listByOrgId(orgid, addCityVo.getHotelType());
            //用户新增城市中已存在的城市
            List<CityNode> existCityList = Lists.newArrayList();
            //用户新增城市中不存在的城市
            List<CityNode> noExistCityList = Lists.newArrayList();
            //在【其它城市】地区的城市
            List<CityNode> otherExistCityList = Lists.newArrayList();
            //筛选已存在的城市、在【其它城市】地区的城市、不存在的城市
            for (CityNode newCity : cityNodeList) {
                boolean flag = false;
                TravelStandardCityConfig temp = new TravelStandardCityConfig();
                for (TravelStandardCityConfig config : cityInfoList) {
                    if (newCity.getCityCode().equals(config.getCityCode())) {
                        flag = true;
                        temp = config;
                        break;
                    }
                }
                if (flag) {
                    if (AreaTypeEnum.TYPE_0.getCode().equals(temp.getAreaType())) {
                        existCityList.add(newCity);
                    } else if (AreaTypeEnum.TYPE_1.getCode().equals(temp.getAreaType())) {
                        otherExistCityList.add(newCity);
                    }
                } else {
                    noExistCityList.add(newCity);
                }
            }
            //添加不存在的城市
            for (CityNode newCity : noExistCityList) {
                TravelStandardCityConfig cityConfig = new TravelStandardCityConfig();
                cityConfig.setAreaId(areaId);
                cityConfig.setCityCode(newCity.getCityCode());
                cityConfig.setCityName(newCity.getCityName());
                cityConfig.setStatus(NumberUtils.INTEGER_ZERO);//0未删除
                cityConfig.setCityNameEn(getPinYinHeadChar(newCity.getCityName()));
                cityConfig.setCityPinyin(getPinYin(newCity.getCityName()).toLowerCase());
                cityConfig.setCityAbbreviation(getAbbreviation(newCity.getCityName()).toUpperCase());
                cityConfig.setDatachangeCreatetime(date);
                cityConfig.setDatachangeLasttime(date);
                cityConfigMapper.insertSelective(cityConfig);
            }
            //移动在【其它城市】地区的城市
            for (CityNode updateCity : otherExistCityList) {
                cityConfigMapper.updateByCityCodeAndOrgId(updateCity.getCityCode(), areaId, orgid, addCityVo.getHotelType());
            }
            //返回存在的城市
            if (!CollectionUtils.isEmpty(existCityList)) {
                Map jsonObject = new HashMap();
                jsonObject.put("cities", existCityList);
                return jsonObject;
            }
        }
        //如果其他区域配置城市列表不为空，为第二次调用，移动已存在的城市
        else {
            for (CityNode updateCity : configuredCityList) {
                cityConfigMapper.updateByCityCodeAndOrgId(updateCity.getCityCode(), areaId, orgid, addCityVo.getHotelType());
            }
        }
        return new HashMap();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map addCountry(AddCityVo addCityVo) {
        Long areaId = addCityVo.getAreaId();
        String orgid = addCityVo.getOrgid();
        Date date = new Date();
        //需要移动的城市
        List<CityNode> configuredCityList = addCityVo.getConfiguredCity();
        //如果其他区域配置城市列表为空，为第一次调用：新增不在的城市；返回已存在的城市（不含【其它城市】地区）；移动在【其它城市】地区的城市
        if (CollectionUtils.isEmpty(configuredCityList)) {
            //用户新增城市
            List<CityNode> cityNodeList = addCityVo.getCity();
            if (CollectionUtils.isEmpty(cityNodeList)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.CITY_NODE_PARAMS_IS_NULL);
            }
            //当前组织下所有城市
            List<TravelStandardCityConfig> cityInfoList = cityConfigMapper.listByOrgId(orgid, addCityVo.getHotelType());
            //用户新增城市中已存在的城市
            List<CityNode> existCityList = Lists.newArrayList();
            //用户新增城市中不存在的城市
            List<CityNode> noExistCityList = Lists.newArrayList();
            //在【其它城市】地区的城市
            List<CityNode> otherExistCityList = Lists.newArrayList();
            //筛选已存在的城市、在【其它城市】地区的城市、不存在的城市
            for (CityNode newCity : cityNodeList) {
                boolean flag = false;
                TravelStandardCityConfig temp = new TravelStandardCityConfig();
                for (TravelStandardCityConfig config : cityInfoList) {

                    if (newCity.getCityCode().equals(config.getCountryCode())) {
                        flag = true;
                        temp = config;
                        break;
                    }
                }
                if (flag) {
                    if (AreaTypeEnum.TYPE_0.getCode().equals(temp.getAreaType())) {
                        existCityList.add(newCity);
                    } else if (AreaTypeEnum.TYPE_1.getCode().equals(temp.getAreaType())) {
                        otherExistCityList.add(newCity);
                    }
                } else {
                    noExistCityList.add(newCity);
                }
            }
            //添加不存在的城市
            for (CityNode newCity : noExistCityList) {
                TravelStandardCityConfig cityConfig = new TravelStandardCityConfig();
                cityConfig.setAreaId(areaId);
                cityConfig.setCountryCode(newCity.getCityCode());
                cityConfig.setCountryName(newCity.getCityName());
                cityConfig.setStatus(NumberUtils.INTEGER_ZERO);//0未删除
                cityConfig.setCountryNameEn(getPinYinHeadChar(newCity.getCityName()));
                cityConfig.setCountryPinyin(getPinYin(newCity.getCityName()).toLowerCase());
                cityConfig.setCountryAbbreviation(getAbbreviation(newCity.getCityName()).toUpperCase());
                cityConfig.setDatachangeCreatetime(date);
                cityConfig.setDatachangeLasttime(date);
                cityConfigMapper.insertSelective(cityConfig);
            }
            //移动在【其它城市】地区的城市
            for (CityNode updateCity : otherExistCityList) {
                cityConfigMapper.updateByCountryCodeAndOrgId(updateCity.getCityCode(), areaId, orgid, addCityVo.getHotelType());
            }
            //返回存在的城市
            if (!CollectionUtils.isEmpty(existCityList)) {
                Map jsonObject = new HashMap();
                jsonObject.put("cities", existCityList);
                return jsonObject;
            }
        }
        //如果其他区域配置城市列表不为空，为第二次调用，移动已存在的城市
        else {
            for (CityNode updateCity : configuredCityList) {
                cityConfigMapper.updateByCountryCodeAndOrgId(updateCity.getCityCode(), areaId, orgid, addCityVo.getHotelType());
            }
        }
        return new HashMap();
    }

    @Override
    public List<CityConfigVo> list(CityConfigVo model) {
        return ListUtils.copyList(cityConfigMapper.list( ObjectUtils.copyProperties(model, TravelStandardCityConfig.class)), CityConfigVo.class);
    }

    //返回中文的大写首字母
    public static String getPinYinHeadChar(String str) {
        if ("重庆".equals(str)) {
            return "C";
        }
        if ("厦门".equals(str)) {
            return "X";
        }
        String convert = "";
        for (int j = 0; j < str.length(); j++) {
            char word = str.charAt(j);
            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
            if (pinyinArray != null) {
                convert += pinyinArray[0].toUpperCase().charAt(0);
                //只取第一个中文的首字母大写
                break;
            } else {
                convert += word;
            }
        }
        return convert;
    }

    //返回中文的拼音
    public static String getPinYin(String str) {
        if ("重庆".equals(str)) {
            return "chongqing";
        }
        if ("厦门".equals(str)) {
            return "xiamen";
        }
        StringBuilder convert = new StringBuilder();
        for (int j = 0; j < str.length(); j++) {
            char word = str.charAt(j);
            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
            if (pinyinArray != null) {
                convert.append(pinyinArray[0], 0, pinyinArray[0].length() - 1);
            } else {
                convert.append(word);
            }
        }
        return convert.toString();
    }

    //返回中文缩写
    public static String getAbbreviation(String str) {
        if ("重庆".equals(str)) {
            return "CX";
        }
        if ("厦门".equals(str)) {
            return "XM";
        }
        StringBuilder convert = new StringBuilder();
        for (int j = 0; j < str.length(); j++) {
            char word = str.charAt(j);
            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
            if (pinyinArray != null) {
                convert.append(pinyinArray[0].toUpperCase().charAt(0));
            } else {
                convert.append(word);
            }
        }
        return convert.toString();
    }

    public static void main(String[] args) {
        String name = "上海";
        System.out.println(getPinYinHeadChar(name));
        System.out.println(getPinYin(name));
        System.out.println(getAbbreviation(name));
    }


    @Override
    public Page page(CityConfigVo model) {
        TravelStandardCityConfig param = ObjectUtils.copyProperties(model, TravelStandardCityConfig.class);
        PageContext.startPage(model.getPageNum(), model.getPageSize());
        List<TravelStandardCityConfig> list = cityConfigMapper.list(param);
        return PageUtils.optPageBy(list, CityConfigVo.class);
    }

}
